﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace Solidi
{
	public class DependencyLifetime : IDependencyLifetime
	{
		private ConcurrentDictionary<object, DependencyGraph> _graphs = new ConcurrentDictionary<object, DependencyGraph>();

		public object Resolve(IDependencyContext context, IDependency dependency)
		{
			DependencyGraph graph = new DependencyGraph(context, dependency);

			object instance = graph.Value;

			if (instance != null)
			{
				//PERF: does not deal with repeat occurances i.e. singleton
				_graphs.TryAdd(instance, graph);

				return instance;
			}

			return null;
		}

		public bool Release(object instance)
		{
			DependencyDisposal disposal = ReleaseForDisposal(instance);

			if (disposal == DependencyDisposal.Disposed)
			{
				DependencyGraph graph = null;

				_graphs.TryRemove(instance, out graph);
					
				return true;
			}
			else if (disposal == DependencyDisposal.ReferenceCountDecremented)
			{
				return true;
			}
			
			return false;
		}

		private DependencyDisposal ReleaseForDisposal(object instance)
		{
			DependencyGraph graph = null;

			if (_graphs.TryGetValue(instance, out graph))
			{
				return graph.Release();
			}

			return DependencyDisposal.ReferenceCountMismatch;
		}
	}
}
